package com.etone.smartAudit.service;

import cn.hutool.core.text.escape.Html4Escape;
import cn.hutool.http.HtmlUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etone.smartAudit.domain.Admin;
import com.etone.smartAudit.domain.Task;
import com.etone.smartAudit.domain.TaskExec;
import com.etone.smartAudit.dto.admin.SimpleAdminDTO;
import com.etone.smartAudit.dto.auditRisk.AuditRiskCheckDTO;
import com.etone.smartAudit.dto.item.ItemExpansionDTO;
import com.etone.smartAudit.dto.item.ItemExpansionSourceDTO;
import com.etone.smartAudit.dto.itemSource.DeviceResourceDTO;
import com.etone.smartAudit.dto.task.*;
import com.etone.smartAudit.enums.CheckState;
import com.etone.smartAudit.enums.TaskType;
import com.etone.smartAudit.error.CustomParameterizedException;
import com.etone.smartAudit.mapper.ItemSourceMapper;
import com.etone.smartAudit.mapper.TaskMapper;
import com.etone.smartAudit.mapstruct.TaskMapstruct;
import com.etone.smartAudit.utils.DateUtil;
import com.etone.smartAudit.utils.Excel.ExcelUtil;
import com.etone.smartAudit.utils.ImageUtil;
import com.etone.smartAudit.vo.PagerVO;
import com.etone.smartAudit.vo.item.ItemExpansionSourceVO;
import com.etone.smartAudit.vo.item.ItemSourceApplyVO;
import com.etone.smartAudit.vo.serviceExpert.ServiceExpertCntVO;
import com.etone.smartAudit.vo.task.*;
import com.etone.smartAudit.vo.tool.ToolBaseVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: 蒋学伟
 * @create: 2020-06-30 10:40:43
 * @Description 任务管理, 避免循环注入引用，此处不用@AllArgsConstructor 使用@Autowired来注释
 */
@Service
@Slf4j
public class TaskService {

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private TaskAuditRecordService taskAuditRecordService;

    @Autowired
    private AuditRiskService auditRiskService;

    @Autowired
    private TaskMapstruct taskMapstruct;

    @Autowired
    private TaskHistoryService taskHistoryService;

    @Autowired
    private ItemService itemService;

    @Autowired
    private AdminPermissionService adminPermissionService;

    @Autowired
    private TaskExecService taskExecService;

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private ToolService toolService;

    @Autowired
    private ServiceExpertService serviceExpertService;

    @Autowired
    private ItemSourceMapper itemSourceMapper;

    @Autowired
    private FileUploadService fileUploadService;

    @Autowired
    private DataModelService dataModelService;

    @Autowired
    private DataMetaTaskService dataMetaTaskService;

    /**
     * 任务列表
     *
     * @param name
     * @param type
     * @param createAdminName
     * @param execAdminName
     * @param createStartTime
     * @param createEndTime
     * @param state
     * @param isOver
     * @param itemId
     * @param createAdminId
     * @param admin
     * @param isDelay
     * @param page
     * @param pageSize
     * @return
     */
    public PagerVO<TaskListVO> list(String name, TaskType type, String createAdminName, String execAdminName, Date createStartTime, Date createEndTime, CheckState state, Boolean isOver, Integer itemId, Integer createAdminId, Admin admin, Boolean isDelay, int page, int pageSize) {
//        if (type == null) {
//            throw new CustomParameterizedException("错误的任务类型");
//        }
        List<TaskType> types = type == null ? null : (type.equals(TaskType.ITEM) ? TaskType.itemTask() : Arrays.asList(type));
        boolean hasPermission = adminPermissionService.hasPermission(admin, "show_all_task_list");
        if (hasPermission) {
            hasPermission = admin.isAdmin();
        }
        boolean finalHasPermission = hasPermission;
        Page<TaskListVO> taskListVOPage = PageHelper.startPage(page, pageSize).doSelectPage(() ->
                taskMapper.findList(name, types, createAdminName, execAdminName, createStartTime, createEndTime, state, isOver, itemId, createAdminId, finalHasPermission ? null : admin.getId(), isDelay, 0)
        );

        return PagerVO.of(taskListVOPage);
    }

    /**
     * 导出
     *
     * @param name
     * @param type
     * @param createAdminName
     * @param execAdminName
     * @param createStartTime
     * @param createEndTime
     * @param state
     * @param isOver
     * @param itemId
     * @param createAdminId
     * @param admin
     * @param isDelay
     * @param response
     */
    public void export(String name, TaskType type, String createAdminName, String execAdminName, Date createStartTime, Date createEndTime, CheckState state, Boolean isOver, Integer itemId, Integer createAdminId, Admin admin, Boolean isDelay, HttpServletResponse response) {
        PagerVO<TaskListVO> taskListVOPager = list(name, type, createAdminName, execAdminName, createStartTime, createEndTime, state, isOver, itemId, createAdminId, admin, isDelay, 1, Integer.MAX_VALUE - 1);
        List<String> header = Arrays.asList("任务名称", "任务类型", "申请人", "申请时间", "预计工时(天)", "期望完成时间", "处理审核人", "是否完结", "完结时间", "状态", "执行人", "实际工时(天)", "评分");
        List<List<String>> taskDatas = new ArrayList<>();
        taskListVOPager.getRows().forEach(taskListVO -> {
            taskDatas.add(taskVO2ListString(taskListVO, 0));
            if (!CollectionUtils.isEmpty(taskListVO.getChildren())) {
                taskListVO.getChildren().forEach(taskListVOChildren -> {
                    taskDatas.add(taskVO2ListString(taskListVOChildren, 1));
                });
            }

        });
        ExcelUtil.export("任务列表", header, taskDatas, response);
    }

    /**
     * @param name
     * @param type
     * @param createAdminName
     * @param execAdminName
     * @param createStartTime
     * @param createEndTime
     * @param state
     * @param isOver
     * @param itemId
     * @param createAdminId
     * @param admin
     * @return
     */
    public TaskAnalysisTotal TaskAnalysisTotal(String name, TaskType type, String createAdminName, String execAdminName, Date createStartTime, Date createEndTime, CheckState state, Boolean isOver, Integer itemId, Integer createAdminId, Admin admin) {
        List<TaskType> types = type == null ? null : (type.equals(TaskType.ITEM) ? TaskType.itemTask() : Arrays.asList(type));
        boolean hasPermission = adminPermissionService.hasPermission(admin, "show_all_task_list");

        //数量和平均分
        TaskAnalysisTotal taskCntAndAvg = taskMapper.countTaskCntAndAvg(name, types, createAdminName, execAdminName, createStartTime, createEndTime, state, isOver, itemId, createAdminId, hasPermission ? null : admin.getId());

        //预计工时和实际工时总量
        TaskAnalysisTotal sumTaskWorkDay = taskMapper.sumTaskWorkDay(name, types, createAdminName, execAdminName, createStartTime, createEndTime, state, isOver, itemId, createAdminId, hasPermission ? null : admin.getId());
        return TaskAnalysisTotal
                .builder()
                .taskCnt(taskCntAndAvg == null ? 0 : taskCntAndAvg.getTaskCnt())
                .scoreAvg(taskCntAndAvg == null ? 0 : taskCntAndAvg.getScoreAvg())
                .dayCnt(sumTaskWorkDay == null ? 0 : sumTaskWorkDay.getDayCnt())
                .expectDayCnt(sumTaskWorkDay == null ? 0 : sumTaskWorkDay.getExpectDayCnt())
                .build();
    }

    /**
     * @param taskListVO
     * @param index      层级
     * @return
     */
    private List<String> taskVO2ListString(TaskListVO taskListVO, int index) {
        String indexStr = "";
        for (int i = 0; i < index; i++) {
            indexStr += " ";
            if (i == index - 1) {
                indexStr += "┣";
            }
        }
        List<TaskExecVO> taskExecs = taskListVO.getTaskExecs();
        //预计工时
        Double expectDayCnt = null;
        //实际工时
        Double dayCnt = null;
        if (!CollectionUtils.isEmpty(taskListVO.getChildren())) {
            expectDayCnt = taskListVO.getChildren().stream().mapToDouble(taskListVOTemp -> {
                List<TaskExecVO> taskExecsTemp = taskListVOTemp.getTaskExecs();
                return CollectionUtils.isEmpty(taskExecsTemp) ? 0d : taskExecsTemp.stream().mapToDouble(taskExecVO -> taskExecVO.getExpectDayCnt() == null ? 0d : taskExecVO.getExpectDayCnt()).sum();
            }).sum();

            dayCnt = taskListVO.getChildren().stream().mapToDouble(taskListVOTemp -> {
                List<TaskExecVO> taskExecsTemp = taskListVOTemp.getTaskExecs();
                return CollectionUtils.isEmpty(taskExecsTemp) ? 0d : taskExecsTemp.stream().mapToDouble(taskExecVO -> taskExecVO.getDayCnt() == null ? 0d : taskExecVO.getDayCnt()).sum();
            }).sum();
        } else {
            expectDayCnt = CollectionUtils.isEmpty(taskExecs) ? null : taskExecs.stream().mapToDouble(taskExecVO -> taskExecVO.getExpectDayCnt() == null ? 0d : taskExecVO.getExpectDayCnt()).sum();
            dayCnt = CollectionUtils.isEmpty(taskExecs) ? null : taskExecs.stream().mapToDouble(taskExecVO -> taskExecVO.getDayCnt() == null ? 0d : taskExecVO.getDayCnt()).sum();
        }
        return Arrays.asList(
                indexStr + taskListVO.getName(),
                taskListVO.getType().getRemark(),
                taskListVO.getCreateAdminName(),
                taskListVO.getCreateTime() == null ? "" : DateUtil.parseDate2String(taskListVO.getCreateTime(), DateUtil.DF_yyyy_MM_dd_HH_mm_ss),
                formatDoubleToString(expectDayCnt),
                taskListVO.getWorkEndTime() == null ? "" : DateUtil.parseDate2String(taskListVO.getWorkEndTime(), DateUtil.DF_yyyy_MM_dd_HH_mm_ss),
                taskListVO.getNodeAdminName(),
                taskListVO.getOver() != null && taskListVO.getOver() ? "是" : "否",
                taskListVO.getOverTime() == null ? "" : DateUtil.parseDate2String(taskListVO.getOverTime(), DateUtil.DF_yyyy_MM_dd_HH_mm_ss),
                taskListVO.getState().getValue(),
                CollectionUtils.isEmpty(taskExecs) ? "--" : taskExecs.stream().map(taskExecVO -> taskExecVO.getAdminName()).collect(Collectors.joining(",")),
                formatDoubleToString(dayCnt),
                formatDoubleToString(taskListVO.getScore()));
    }

    private String formatDoubleToString(Double dou) {
        return dou == null ? "--" : dou.toString();
    }

    /**
     * 添加任务
     *
     * @param task
     */
    public void add(Task task) {
        taskMapper.insert(task);
    }

    /**
     * 更新任务
     *
     * @param task
     * @param admin
     * @return
     */
    public int update(Task task, Admin admin) {
        task.setUpdateTime(new Date());
        task.setUpdateAdminId(admin.getId());
        task.setUpdateAdminName(admin.getNickName());
        return taskMapper.updateById(task);
    }

    /**
     * 编辑｜添加任务
     *
     * @param baseTaskDTO
     * @param id
     */
    public void save(BaseTaskDTO baseTaskDTO, Integer id) {

    }

    public Task get(Integer id) {
        Task task = taskMapper.findById(id);
        if (task == null) {
            throw new CustomParameterizedException("任务不存在");
        }
        List<TaskExec> taskExecs = taskExecService.findByTaskId(id);
        task.setTaskExecs(taskExecs);
        return task;
    }

    public Task get(Integer id, TaskType taskType) {
        Task task = taskMapper.findOneByItemTypeIdAndType(id, taskType);
        if (task == null) {
            throw new CustomParameterizedException("未找到相关的任务");
        }
        return task;
    }

    /**
     * 获取有权限的任务
     *
     * @param id
     * @param admin
     * @return
     */
    public Task getPermissionTask(Integer id, Admin admin) {
        boolean hasPermission = adminPermissionService.hasPermission(admin, "show_all_task_list");
        Task task = taskMapper.findPermissionTask(hasPermission ? null : admin.getId(), id);
        if (task == null) {
            throw new CustomParameterizedException("任务不存在");
        }
        List<TaskExec> taskExecs = taskExecService.findByTaskId(id);
        task.setTaskExecs(taskExecs);
        return task;
    }

    /**
     * 添加任务
     *
     * @param baseTaskDTO
     * @param admin
     * @param taskType
     */
    @Transactional(rollbackFor = Exception.class)
    public void add(BaseTaskDTO baseTaskDTO, Admin admin, TaskType taskType) {
        switch (taskType) {
            case DATA_MODEL_AUTH:
            case RESOURCE_APPLY:
            case RESOURCE_EXPANSION:
            case NEW_DATA_APPLY: {
                SimpleAdminDTO checking_member = dictionaryService.getCheckingMember("work_task_source_checking_member");
                baseTaskDTO.setNodeAdminId(checking_member.getId());
                baseTaskDTO.setNodeAdminName(checking_member.getNickName());
                baseTaskDTO.setContact(admin.getNickName());
                baseTaskDTO.setContactTel(admin.getTel());
                baseTaskDTO.setWorkEndTime(null);
            }
            break;
            case MAN_MADE_STORAGE: {
                SimpleAdminDTO checking_member = dictionaryService.getCheckingMember("work_task_service_checking_member");
                baseTaskDTO.setNodeAdminId(checking_member.getId());
                baseTaskDTO.setNodeAdminName(checking_member.getNickName());
                baseTaskDTO.setContact(admin.getNickName());
                baseTaskDTO.setContactTel(admin.getTel());
                baseTaskDTO.setWorkEndTime(null);
            }
            break;
            case RESOURCE_DEVICE: {
                ResourceDeviceTaskDTO resourceDeviceTaskDTO = (ResourceDeviceTaskDTO) baseTaskDTO;
                for (DeviceResourceDTO deviceResource : resourceDeviceTaskDTO.getDeviceResources()) {
                    Boolean checkExpirationTime = itemSourceMapper.checkDeviceExpirationTime(deviceResource.getItemSourceId(), null);
                    if (checkExpirationTime) {
                        throw new CustomParameterizedException(deviceResource.getItemSourceName() + "已被占用");
                    }
                }
                SimpleAdminDTO checking_member = dictionaryService.getCheckingMember("work_task_source_checking_member");
                baseTaskDTO.setNodeAdminId(checking_member.getId());
                baseTaskDTO.setNodeAdminName(checking_member.getNickName());
                baseTaskDTO.setContact(admin.getNickName());
                baseTaskDTO.setContactTel(admin.getTel());
                baseTaskDTO.setWorkEndTime(null);
            }
            break;
            default:
        }
        //联系人
        if (StringUtils.isEmpty(baseTaskDTO.getContact())) {
            baseTaskDTO.setContact(admin.getNickName());
        }
        if (StringUtils.isEmpty(baseTaskDTO.getContactTel())) {
            baseTaskDTO.setContactTel(admin.getTel());
        }
        String detail = JSON.toJSONStringWithDateFormat(baseTaskDTO, "yyyy-MM-dd HH:mm:ss");
        Date now = new Date();

        Task task = Task
                .builder()
                .createAdminId(admin.getId())
                .createAdminName(admin.getNickName())
                .createTime(now)
                .updateAdminId(admin.getId())
                .updateAdminName(admin.getNickName())
                .updateTime(now)
                .detail(detail)
                .state(CheckState.CHECKING)
                .over(false)
                .type(taskType)
                .build();
        taskMapstruct.baseTaskDTOCopyTo(task, baseTaskDTO);
        add(task);

        //添加执行人
        List<SimpleAdminDTO> execAdmins = baseTaskDTO.getExecAdmins();
        if (!CollectionUtils.isEmpty(execAdmins)) {
            List<TaskExec> taskExecs = execAdmins.stream().map(execAdmin -> TaskExec.builder().state(CheckState.CHECKING).taskId(task.getId()).adminId(execAdmin.getId()).dayCnt(0d).build()).collect(Collectors.toList());
            taskExecService.add(taskExecs, task.getId());
        }

        //清理临时文件
        List<String> urls = ImageUtil.regFileJsonUrl(detail);
        if (!CollectionUtils.isEmpty(urls)) {
            fileUploadService.deleteFileForUpdateByURL(urls, null);
        }
    }

    /**
     * 添加工作任务
     *
     * @param workTaskDTO
     * @param admin
     */
    @Transactional(rollbackFor = Exception.class)
    public void addWorkTask(WorkTaskDTO workTaskDTO, Admin admin) {

        if (workTaskDTO.getDataTask() != null) {
            workTaskDTO.getDataTask().setId(null);

            SimpleAdminDTO checking_member = dictionaryService.getCheckingMember("work_task_data_checking_member");
            workTaskDTO.getDataTask().setNodeAdminId(checking_member.getId());
            workTaskDTO.getDataTask().setNodeAdminName(checking_member.getNickName());

            add(workTaskDTO.getDataTask(), admin, TaskType.WORK_DATA);
        }
        if (workTaskDTO.getItemSourceTask() != null) {
            workTaskDTO.getItemSourceTask().setId(null);

            SimpleAdminDTO checking_member = dictionaryService.getCheckingMember("work_task_source_checking_member");
            workTaskDTO.getItemSourceTask().setNodeAdminId(checking_member.getId());
            workTaskDTO.getItemSourceTask().setNodeAdminName(checking_member.getNickName());
            add(workTaskDTO.getItemSourceTask(), admin, TaskType.WORK_ITEM_SOURCE);
        }
        if (workTaskDTO.getServiceExpertTask() != null) {
            workTaskDTO.getServiceExpertTask().setId(null);

            SimpleAdminDTO checking_member = dictionaryService.getCheckingMember("work_task_service_checking_member");
            workTaskDTO.getServiceExpertTask().setNodeAdminId(checking_member.getId());
            workTaskDTO.getServiceExpertTask().setNodeAdminName(checking_member.getNickName());

            add(workTaskDTO.getServiceExpertTask(), admin, TaskType.WORK_SERVICE);
        }
        if (workTaskDTO.getToolTask() != null) {
            workTaskDTO.getToolTask().setId(null);

            SimpleAdminDTO checking_member = dictionaryService.getCheckingMember("work_task_tool_checking_member");
            workTaskDTO.getToolTask().setNodeAdminId(checking_member.getId());
            workTaskDTO.getToolTask().setNodeAdminName(checking_member.getNickName());

            add(workTaskDTO.getToolTask(), admin, TaskType.WORK_TOOL);
        }

    }

    /**
     * 编辑任务
     *
     * @param id
     * @param baseTaskDTO
     * @param admin
     * @param taskType
     */
    public void edit(Integer id, BaseTaskDTO baseTaskDTO, Admin admin, TaskType taskType) {

        Task task = get(id);
        if (!CheckState.isArrowEdit(task.getState())) {
            throw new CustomParameterizedException(task.getState().getValue() + "状态无法编辑");
        }
        //旧图片
        List<String> oldImages = ImageUtil.regFileJsonUrl(task);

        //保存历史记录
        taskHistoryService.insert(task, admin);

        String detail = JSON.toJSONStringWithDateFormat(baseTaskDTO, "yyyy-MM-dd HH:mm:ss");
        taskMapstruct.baseTaskDTOCopyTo(task, baseTaskDTO);
        task.setState(CheckState.CHECKING);
        task.setOver(false);
        task.setType(taskType);
        task.setDetail(detail);

        update(task, admin);

        //清理文件
        List<String> newImages = ImageUtil.regFileJsonUrl(detail);
        fileUploadService.deleteFileForUpdateByURL(newImages, oldImages);

    }

    /**
     * 编辑工作任务
     *
     * @param id
     * @param workTaskDTO
     * @param admin
     */
    public void editWorkTask(Integer id, WorkTaskDTO workTaskDTO, Admin admin) {
        if (workTaskDTO.getDataTask() != null) {
            edit(workTaskDTO.getDataTask().getId(), workTaskDTO.getDataTask(), admin, TaskType.WORK_DATA);
        }
        if (workTaskDTO.getItemSourceTask() != null) {
            edit(workTaskDTO.getItemSourceTask().getId(), workTaskDTO.getItemSourceTask(), admin, TaskType.WORK_ITEM_SOURCE);
        }
        if (workTaskDTO.getServiceExpertTask() != null) {
            edit(workTaskDTO.getServiceExpertTask().getId(), workTaskDTO.getServiceExpertTask(), admin, TaskType.WORK_SERVICE);
        }
        if (workTaskDTO.getToolTask() != null) {
            edit(workTaskDTO.getToolTask().getId(), workTaskDTO.getToolTask(), admin, TaskType.WORK_TOOL);
        }
    }

    /**
     * 任务审批
     *
     * @param id
     * @param taskAuditDTO
     * @param admin
     */
    @Transactional(rollbackFor = Exception.class)
    public void audit(Integer id, TaskAuditDTO taskAuditDTO, Admin admin) {
        Task task = get(id);

        //校验任务状态
        Boolean checkNextState = CheckState.checkNextState(taskAuditDTO.getState(), task.getState(), task.getType());
        if (!checkNextState) {
            throw new CustomParameterizedException("审核状态错误");
        }

        //校验审批人
        if (!checkAuditAdmin(task, admin)) {
            throw new CustomParameterizedException("您不是当前操作人");
        }

        //添加审核记录
        taskAuditRecordService.add(task, taskAuditDTO, admin);

        Date now = new Date();

        switch (taskAuditDTO.getState()) {
            case CHECKING:
                if (taskAuditDTO.getNodeAdminId() != null) {
                    task.setNodeAdminId(taskAuditDTO.getNodeAdminId());
                    task.setNodeAdminName(taskAuditDTO.getNodeAdminName());
                }
                break;
            case EXECUTE_NOT_START:
                //审核人通过，提交给执行人
                if (CollectionUtils.isEmpty(taskAuditDTO.getTaskExecs())) {
                    throw new CustomParameterizedException("请选择执行人");
                }
                List<TaskExec> taskExecs =
                        taskAuditDTO.getTaskExecs().stream().map(taskExecDTO -> TaskExec.builder().adminId(taskExecDTO.getAdminId()).adminName(taskExecDTO.getAdminName()).expectDayCnt(taskExecDTO.getDayCnt()).serviceExpertId(taskExecDTO.getServiceExpertId()).serviceExpertName(taskExecDTO.getServiceExpertName()).state(CheckState.EXECUTE_NOT_START).taskId(task.getId()).build()).collect(Collectors.toList());
                task.setTaskExecs(taskExecs);

                //更新执行人
                taskExecService.add(taskExecs, id);
                break;
            case EXECUTE_STARTING:
                //执行人开始执行任务

                //标识提交状态
                taskExecService.taskExecStart(id, admin.getId());
                switch (task.getType()) {
                    case MAN_MADE_STORAGE: {
                        Integer itemTypeId = task.getItemTypeId();
                        dataMetaTaskService.auditResult(itemTypeId, taskAuditDTO.getState(), null, admin);
                    }
                    break;
                    default:

                }
                break;
            case EXECUTE_CHECKING:
                //执行人执行任务完成，转给执行审核人审核

                //标识提交状态
                taskExecService.taskExecEnd(id, admin.getId(), taskAuditDTO.getWorkTime(), taskAuditDTO.getFile(), null, null);

                //判断全部执行人知否完成任务，如果全部完成任务可进入下一步审核
                if (!taskExecService.checkTaskExecOver(id)) {
                    return;
                }
                break;
            case PASS:
                //执行人完成任务，给审核人审核
                task.setScore(taskAuditDTO.getScore());
                task.setOver(true);
                task.setOverTime(now);
                if (task.getParentId() != null && task.getParentId() != 0 && TaskType.isWorkTask(task.getType())) {
                    List<TaskListVO> childrenVOS = taskMapper.findChildrenVO(task.getParentId());
                    if (!CollectionUtils.isEmpty(childrenVOS)) {
                        boolean hasNotOver = childrenVOS.stream().anyMatch(taskChild -> !taskChild.getOver() && taskChild.getId().intValue() != task.getId().intValue());
                        if (childrenVOS.size() == 1 || !hasNotOver) {
                            Task parentTask = get(task.getParentId());
                            parentTask.setOver(true);
                            parentTask.setOverTime(now);
                            parentTask.setState(taskAuditDTO.getState());
                            taskMapper.updateById(parentTask);
                        }
                    }
                }


                //执行通过后的操作
                switch (task.getType()) {
                    case ITEM_RISK://审计风险
                    {
                        Integer auditRiskId = task.getItemTypeId();
                        auditRiskService.check(auditRiskId, AuditRiskCheckDTO.builder().state(CheckState.PASS).build());
                    }
                    break;
                    case ITEM_ITEM://项目任务
                    {
                        Integer itemId = task.getItemTypeId();
                        itemService.check(itemId, CheckState.PASS);
                    }
                    break;
                    case ITEM_ITEM_SOURCE: //项目任务资源申请｜扩容
                    {
                    }
                    break;
                    case RESOURCE_EXPANSION:
                        //资源扩容
                    case RESOURCE_APPLY: {
                        //资源申请
                        ResourceTaskDTO resourceTaskDTO = JSON.parseObject(task.getDetail(), ResourceTaskDTO.class);


                        String extendInfo = taskAuditDTO.getExtendInfo();
                        if (StringUtils.isEmpty(extendInfo)) {
                            throw new CustomParameterizedException("资源信息不能为空");
                        }
                        List<ItemExpansionSourceVO> itemExpansionSources = JSONArray.parseArray(extendInfo, ItemExpansionSourceVO.class);
                        List<ItemExpansionSourceDTO> itemExpansionSourceDTOS = JSONArray.parseArray(extendInfo, ItemExpansionSourceDTO.class);
                        itemService.passExpansion(admin, task.getItemId(),
                                ItemExpansionDTO.builder().remark(resourceTaskDTO.getRemark()).itemExpansionSources(itemExpansionSourceDTOS).isFirst(task.getType().equals(TaskType.RESOURCE_APPLY)).contactTel(resourceTaskDTO.getContactTel()).contact(resourceTaskDTO.getContact()).cause(resourceTaskDTO.getCause()).build(),
                                itemExpansionSources);

                        //更新执行信息
                        taskExecService.taskExecEnd(id, admin.getId(), null, null, extendInfo, CheckState.PASS);
                    }
                    break;
                    case MAN_MADE_STORAGE: {
                        Integer itemTypeId = task.getItemTypeId();
                        dataMetaTaskService.auditResult(itemTypeId, taskAuditDTO.getState(), null, admin);
                    }
                    break;
                    case WORK_TOOL://工具中台任务
                        ToolWorkTaskVO workTaskVO = JSON.parseObject(task.getDetail(), ToolWorkTaskVO.class);
                        List<ToolBaseVO> tools = workTaskVO.getTools();
                        if (!CollectionUtils.isEmpty(tools)) {
                            toolService.addApplyCnt(tools.stream().map(tool -> tool.getId()).collect(Collectors.toList()));
                        }

                        break;
                    case WORK_SERVICE:
                        ServiceExpertWorkTaskVO serviceExpertWorkTaskVO = JSON.parseObject(task.getDetail(), ServiceExpertWorkTaskVO.class);
                        List<ServiceExpertCntVO> serviceExpertCnt = serviceExpertWorkTaskVO.getServiceExpertCnt();
                        if (!CollectionUtils.isEmpty(serviceExpertCnt)) {
                            serviceExpertService.addApplyCnt(serviceExpertCnt.stream().map(serviceExpertCntVO -> serviceExpertCntVO.getId()).collect(Collectors.toList()));
                        }
                        break;
                    case DATA_MODEL_AUTH: {
                        //执行审核通过操作
                        DataModelAuthTaskDTO dataModelAuthTaskDTO = JSON.parseObject(task.getDetail(), DataModelAuthTaskDTO.class);
                        if (!CollectionUtils.isEmpty(dataModelAuthTaskDTO.getDataModelApplies())) {
                            List<Integer> dataModelIds = dataModelAuthTaskDTO.getDataModelApplies().stream().map(dataModelApplyDTO -> dataModelApplyDTO.getId()).collect(Collectors.toList());
                            dataModelService.auditPass(dataModelAuthTaskDTO.getItemId(), dataModelIds);
                        }

                    }
                    break;
                    case WORK_ITEM_SOURCE:
                        ItemSourceWorkTaskVO itemSourceWorkTaskVO = JSON.parseObject(task.getDetail(), ItemSourceWorkTaskVO.class);
                        List<ItemSourceApplyVO> itemSources = itemSourceWorkTaskVO.getItemSources();
                        if (!CollectionUtils.isEmpty(itemSources)) {
                            itemSourceMapper.addApplyCnt(itemSources.stream().map(itemSourceApplyVO -> itemSourceApplyVO.getId()).collect(Collectors.toList()), 1);
                        }
                        break;
                    case RESOURCE_DEVICE: {
                        ResourceDeviceTaskDTO resourceDeviceTaskDTO = JSON.parseObject(task.getDetail(), ResourceDeviceTaskDTO.class);
                        itemService.updateItemDeviceResource(resourceDeviceTaskDTO.getDeviceResources());

                    }
                    break;
                    default:
                }
                break;
            case EXECUTE_REJECT:
                taskExecService.taskExecReject(id);
                break;
            case REJECT:
                switch (task.getType()) {
                    case ITEM_RISK://审计风险
                    {
                        Integer auditRiskId = task.getItemTypeId();
                        auditRiskService.check(auditRiskId, AuditRiskCheckDTO.builder().state(CheckState.REJECT).build());
                    }
                    break;
                    case ITEM_ITEM://项目任务
                    {
                        Integer itemId = task.getItemTypeId();
                        itemService.check(itemId, CheckState.REJECT);
                    }
                    break;
                    case ITEM_ITEM_SOURCE: //项目任务资源申请｜扩容
                    {
                    }
                    break;
                    case MAN_MADE_STORAGE: {
                        Integer itemTypeId = task.getItemTypeId();
                        dataMetaTaskService.auditResult(itemTypeId, taskAuditDTO.getState(), taskAuditDTO.getRemark(), admin);
                    }
                    break;
                    default:
                }
            default:
        }
        task.setState(taskAuditDTO.getState());

        //更新任务
        update(task, admin);

        //清理文件
        fileUploadService.deleteFileByFileDTO(Arrays.asList(taskAuditDTO.getFile()), false, true);
    }

    /**
     * 校验审批人
     *
     * @param task  当前任务
     * @param admin 当前审核人
     * @return
     */
    public Boolean checkAuditAdmin(Task task, Admin admin) {
        if (admin.isAdmin()) {
            return true;
        }
        if (task == null || admin == null || admin.getId() == null) {
            return false;
        }
        //项目任务
        if (TaskType.isItemTask(task.getType())) {
            return task.getNodeAdminId().intValue() == admin.getId().intValue();
        }
        //模型任务/工作任务/临时资源申请
        switch (task.getState()) {
            case EXECUTE_NOT_START:
            case EXECUTE_STARTING:
            case EXECUTE_REJECT:
                //执行人校验
                List<TaskExec> taskExecs = taskExecService.findByTaskId(task.getId());
                if (CollectionUtils.isEmpty(taskExecs)) {
                    return false;
                }
                return taskExecs.stream().anyMatch(taskExec -> taskExec.getAdminId().intValue() == admin.getId().intValue());
            default:
                return task.getNodeAdminId().intValue() == admin.getId().intValue();
        }
    }

    /**
     * 删除任务
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void delete(Integer id, Admin admin) {
        Task task = get(id);
        delete(task, admin);
    }

    /**
     * 批量删除任务
     *
     * @param ids
     */
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Integer> ids, Admin admin) {
        ids.forEach(id -> delete(id, admin));
    }

    /**
     * 通过对象删除任务
     *
     * @param task
     * @param admin
     */
    @Transactional(rollbackFor = Exception.class)
    public void delete(Task task, Admin admin) {
        if (!CheckState.isArrowDelete(task.getState())) {
            throw new CustomParameterizedException(task.getName() + task.getState().getValue() + "状态无法删除");
        }
        if (admin == null || admin.isAdmin() || admin.getId().intValue() == task.getCreateAdminId().intValue()) {
            int count = taskMapper.deleteById(task.getId());

            //如果没有子任务了，删除主任务
            if (task.getParentId() != null && task.getParentId() != 0 && !taskMapper.hasChildren(task.getParentId())) {
                delete(task.getParentId(), admin);
            }
            if (count > 0) {
                doAfterDelete(task.getId());
            }
            return;
        }
        throw new CustomParameterizedException("您无权删除该任务");
    }

    /**
     * 删除"项目任务"任务
     *
     * @param itemTypeId
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteByItemTypeId(Integer itemTypeId, TaskType taskType) {
        //获取相应的任务
        List<Task> tasks = taskMapper.findByParams(itemTypeId, taskType);

        //删除相应的任务
        tasks.forEach(task -> delete(task, null));
    }

    /**
     * 批量删除"项目任务"任务
     *
     * @param itemTypeIds
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteByItemTypeId(List<Integer> itemTypeIds, TaskType taskType) {
        itemTypeIds.forEach(itemTypeId -> deleteByItemTypeId(itemTypeId, taskType));
    }

    /**
     * 删除任务之后的操作
     *
     * @param id
     */
    private void doAfterDelete(Integer id) {
        //删除审核记录
        taskAuditRecordService.deleteByTaskId(id);

        //删除编辑记录
        taskHistoryService.deleteByTaskId(id);

        //删除执行人记录
        taskExecService.deleteByTaskId(id);
    }

    /**
     * 模型任务详情
     *
     * @param id
     * @return
     */
    public ModuleTaskDetailVO moduleTaskDetail(Integer id) {
        Task task = get(id);
        if (!TaskType.MODULE.equals(task.getType())) {
            throw new CustomParameterizedException("该任务不是模型任务");
        }
        ModuleTaskDetailVO moduleTaskDetailVO = JSON.parseObject(task.getDetail(), ModuleTaskDetailVO.class);
        taskMapstruct.copyToModuleTaskDetailVO(task, moduleTaskDetailVO);
        return moduleTaskDetailVO;
    }

    /**
     * 工作任务详情
     *
     * @param id
     * @return
     */
    public WorkTaskDetailVO workTaskDetail(Integer id) {
        Task task = get(id);
        if (!TaskType.isWorkTask(task.getType())) {
            throw new CustomParameterizedException("该任务不是工作任务");
        }
        if (task.getParentId() != null && task.getParentId() > 0) {
            return workTaskDetail(task.getParentId());
        }
        WorkTaskDetailVO workTaskDetailVO = WorkTaskDetailVO.builder().name(task.getName()).build();
        List<Task> children = taskMapper.findChildren(id);
        children.forEach(child -> {
            switch (child.getType()) {
                case WORK_SERVICE:
                    ServiceExpertWorkTaskVO serviceExpertWorkTaskVO = JSON.parseObject(child.getDetail(), ServiceExpertWorkTaskVO.class);
                    taskMapstruct.copyToServiceExpertWorkTaskVO(child, serviceExpertWorkTaskVO);
                    workTaskDetailVO.setServiceExpertTask(serviceExpertWorkTaskVO);
                    break;
                case WORK_ITEM_SOURCE:
                    ItemSourceWorkTaskVO itemSourceWorkTaskVO = JSON.parseObject(child.getDetail(), ItemSourceWorkTaskVO.class);
                    taskMapstruct.copyToItemSourceWorkTaskVO(child, itemSourceWorkTaskVO);
                    workTaskDetailVO.setItemSourceTask(itemSourceWorkTaskVO);
                    break;
                case WORK_TOOL:
                    ToolWorkTaskVO toolTask = JSON.parseObject(child.getDetail(), ToolWorkTaskVO.class);
                    taskMapstruct.copyToToolWorkTaskVO(child, toolTask);
                    workTaskDetailVO.setToolTask(toolTask);
                    break;
                case WORK_DATA:
                    DataWorkTaskVO dataWorkTaskVO = JSON.parseObject(child.getDetail(), DataWorkTaskVO.class);
                    taskMapstruct.copyToDataWorkTaskVO(child, dataWorkTaskVO);
                    workTaskDetailVO.setDataTask(dataWorkTaskVO);
                    break;
                default:
                    throw new CustomParameterizedException("无效任务类型");

            }
        });
        return workTaskDetailVO;
    }

    /**
     * 临时资源申请
     *
     * @param id
     * @return
     */
    public TemporaryTaskDetailVO temporaryTaskDetail(Integer id) {
        Task task = get(id);
        if (!TaskType.isTemporaryTask(task.getType())) {
            throw new CustomParameterizedException("该任务不是临时任务");
        }
        TemporaryTaskDetailVO temporaryDetailVO = JSON.parseObject(task.getDetail(), TemporaryTaskDetailVO.class);
        taskMapstruct.copyToTemporaryTaskDetailVO(task, temporaryDetailVO);
        return temporaryDetailVO;
    }

    /**
     * 服务支撑中台任务详情
     *
     * @param id
     * @return
     */
    public ServiceExpertWorkTaskVO workServiceTaskDetail(Integer id) {
        Task task = get(id);
        if (!task.getType().equals(TaskType.WORK_SERVICE)) {
            throw new CustomParameterizedException("该任务不是服务支撑中台任务");
        }
        ServiceExpertWorkTaskVO serviceExpertWorkTaskVO = JSON.parseObject(task.getDetail(), ServiceExpertWorkTaskVO.class);
        return serviceExpertWorkTaskVO;
    }

    /**
     * 数据中台-数据任务申请成功次数
     *
     * @return
     */
    public int findWorkDataApplyCnt() {
        return taskMapper.findWorkDataApplyCnt();
    }

    /**
     * 通用任务详情
     *
     * @param id
     * @param admin
     * @return
     */
    public TaskDetailVO detail(Integer id, Admin admin) {
        Task task = getPermissionTask(id, admin);
        //过滤脚本
        String detail = task.getDetail();
        try {
            JSONObject json = JSON.parseObject(detail);
            JSONObject info = json.getJSONObject("info");
            String remark = info.getString("remark");
            info.put("remark", HtmlUtil.filter(remark));
            json.put("info", info);
            task.setDetail(json.toString());
        } catch (Exception e) {
            log.error("解析detail错误", e);
        }
        return taskMapstruct.getTaskDetailVO(task);
    }

    /**
     * 我的任务统计个数
     *
     * @param admin
     * @return
     */
    public MyTaskAnalysis myTaskAnalysis(Admin admin) {

        boolean hasPermission = false;// adminPermissionService.hasPermission(admin, "show_all_task_list");
        if (hasPermission) {
            hasPermission = admin.isAdmin();// adminPermissionService.hasPermission(admin, "show_all_task_list");
        }
        //代办任务个数
        Integer agencyCnt = taskMapper.countAgency(hasPermission ? null : admin.getId());

        //已办任务个数
        Integer doneCnt = taskMapper.countDone(hasPermission ? null : admin.getId());

        //我的发起任务个数
        Integer createCnt = taskMapper.countCreate(admin.getId());

        //逾期任务个数
        Integer beOverdueCnt = taskMapper.countBeOverdue(hasPermission ? null : admin.getId());

        return MyTaskAnalysis.builder().agencyCnt(agencyCnt).doneCnt(doneCnt).createCnt(createCnt).beOverdueCnt(beOverdueCnt).build();
    }

    /**
     * 我申请的数据模型任务
     *
     * @param name
     * @param state
     * @param admin
     * @param page
     * @param pageSize
     * @return
     */
    public PagerVO<MyDataModelAuthTask> myDataModelAuthList(String name, CheckState state, Admin admin, int page, int pageSize) {
        Page<MyDataModelAuthTask> myDataModelAuthTaskPage = PageHelper.startPage(page, pageSize).doSelectPage(() -> taskMapper.myDataModelAuthList(name, state, admin.isAdmin() ? null : admin.getId()));
        return PagerVO.of(myDataModelAuthTaskPage);
    }

    /**
     * 个人申请服务器存储资源
     * @param admin
     * @return
     */
    public List<ItemExpansionSourceDTO> itemExpansionSource(Admin admin) {
        PagerVO<TaskListVO> list = list(null, TaskType.RESOURCE_APPLY, null, null, null, null, CheckState.PASS, true, null, admin.getId(), admin, null, 1, 1000);
        List<ItemExpansionSourceDTO> itemExpansionSources = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list.getRows())) {
            for (TaskListVO taskListVO : list.getRows()) {
                ResourceTaskDTO resourceTaskDTO = JSON.parseObject(taskListVO.getDetail(), ResourceTaskDTO.class);
                List<ItemExpansionSourceDTO> sources = resourceTaskDTO.getItemExpansionSources();
                if (sources != null){
                    for (ItemExpansionSourceDTO source : sources) {
                        if ("存储".equals(source.getItemSourceName()) || "FTP".equals(source.getItemSourceName())){
                            if (!itemExpansionSources.contains(source)) {
                                itemExpansionSources.add(source);
                            }
                        }
                    }
                }
            }
        }
        return itemExpansionSources;
    }
}
